package thread;

import java.util.List;
import java.util.Vector;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Semaphore;

/**
 * <p>Title:Test</p>
 * <p>Description:现有的程序代码模拟产生了16个日志对象，
 * 				    并且需要运行16秒才能打印完这些日志，
 * 				    请在程序中增加4个线程去调用parseLog()方法来分头打印这16个日志对象，
 * 				    程序只需要运行4秒即可打印完这些日志对象</p>
 * @author	xiongfei
 * @date	2017年6月23日 下午3:21:44
 * @version 1.0
 */
public class Test {

	public static void main(String[] args) {
		final BlockingQueue<String> queue = new ArrayBlockingQueue<String>(16);
		ExecutorService pool = Executors.newFixedThreadPool(4);
		for (int i = 0; i <= 4; i++) {
			pool.execute(new Runnable() {
				@Override
				public void run() {
					while (true) {
						try {
							/*虽然queue为堵塞队列，但实际上take方法拿取值消耗时间基本可以忽略不计
							所以queue.take虽然为线程同步，但可以在同一时间打印出来
							如果我们把parseLog方法设置为同步，将可以看到时间一秒打印一条
							*/
							String log = queue.take();
							parseLog(log);

						} catch (Exception e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						}
					}

				}
			});
		}
		/*for (int i = 0; i <= 4; i++) {
			new Thread(new Runnable() {
				@Override
				public void run() {
					while (true) {
						try {
							虽然queue为堵塞队列，但实际上take方法拿取值消耗时间基本可以忽略不计
							所以queue.take虽然为线程同步，但可以在同一时间打印出来
							如果我们把parseLog方法设置为同步，将可以看到时间一秒打印一条
							
							String log = queue.take();
							parseLog(log);

						} catch (Exception e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						}
					}
				}

			}).start();
		}*/

		System.out.println("begin:" + (System.currentTimeMillis() / 1000));
		/*模拟处理16行日志，下面的代码产生了16个日志对象，当前代码需要运行16秒才能打印完这些日志。
		修改程序代码，开四个线程让这16个对象在4秒钟打完。
		*/
		for (int i = 0; i < 16; i++) { // 这行代码不能改动
			final String log = "" + (i + 1);// 这行代码不能改动
			{
				try {
					queue.put(log);
				} catch (Exception e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				// Test.parseLog(log);
			}
		}
	}

	// parseLog方法内部的代码不能改动
	public static void parseLog(String log) {
		// synchronized (Test.class) {
		System.out.println(log + ":" + (System.currentTimeMillis() / 1000));

		try {
			Thread.sleep(1000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		// }
	}

}
